﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace PlatypusPlanner.ViewControls.Utility
{
    public class ControlUtility
    {
        private static ControlUtility _controlUtility;

        static ControlUtility()
        {
            _controlUtility = new ControlUtility();
        }

        public static ControlUtility Instance()
        {
            return _controlUtility;
        }

        public string CreateAnchorLinkString(string url, string target, string text, string title, string imageUrl, string linkCssClass, string imageCssClass, bool noFollow, string objectId = "-1")
        {
            StringBuilder sb = new StringBuilder();

            if (!string.IsNullOrEmpty(url))
            {
                sb.Append("<a href=\"").Append(url).Append("\" ");

                if (!string.IsNullOrEmpty(target))
                    sb.Append(" target=\"").Append(target).Append("\" ");

                if (!string.IsNullOrEmpty(title))
                    sb.Append(" title=\"").Append(title).Append("\" ");

                if (!string.IsNullOrEmpty(linkCssClass))
                    sb.Append(" class=\"").Append(linkCssClass).Append("\" ");

                if (noFollow)
                    sb.Append(" rel=\"nofollow\" ");

                if (objectId != "-1")
                    sb.Append(" data-object-id=\"").Append(objectId).Append("\" ");

                sb.Append(">");
            }

            if (string.IsNullOrEmpty(imageUrl))
                sb.Append(text);
            else
                sb.Append(CreateImageString(imageUrl, text, imageCssClass));

            if (!string.IsNullOrEmpty(url))
                sb.Append("</a>");

            return sb.ToString();
        }

        public string CreateImageString(string imageUrl, string altText, string cssClass)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<img src=\"").Append(imageUrl).Append("\"");

            if (!string.IsNullOrEmpty(cssClass))
                sb.Append(" class=\"").Append(cssClass).Append("\"");

            sb.Append(" alt=\"").Append(altText).Append("\" />");

            return sb.ToString();
        }

        /// <summary>
        /// Gets current bound object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="currentControl"></param>
        /// <returns></returns>
        public virtual T GetCurrentBoundObject<T>(Control currentControl) where T : class
        {
            DataContainer dataContainer = GetParentDataContainer(currentControl);
            while (dataContainer != null)
            {
                if (dataContainer.GetObject<T>() != null)
                    return dataContainer.GetObject<T>();

                dataContainer = GetParentDataContainer(dataContainer.Control);
            }

            return default(T);
        }
        public virtual T GetNamingContainerObject<T>(Control currentControl) where T : class
        {
            if (currentControl.NamingContainer != null)
            {
                if (currentControl.NamingContainer.Parent is T)
                    return currentControl.NamingContainer.Parent as T;

            }
            return null;
        }

        public void PopulateListOfControlsFromControlCollection<T>(ControlCollection currentControl, List<T> containerList) where T : class
        {
            if (currentControl != null)
                foreach (Control c in currentControl)
                {
                    T box = ControlUtility.Instance().FindControlOfType<T>(c);
                    if (box != null)
                        containerList.Add(box);

                    if (c.HasControls())
                        PopulateListOfControlsFromControlCollection(c.Controls, containerList);
                }
        }
        public void SelectListControlItem(ListControl list, string itemValue, bool allowMultipleSelections = false)
        {
            if (!string.IsNullOrEmpty(itemValue))
            {
                ListItem item = list.Items.FindByValue(itemValue);
                if (item != null)
                {
                    if (!allowMultipleSelections)
                        list.SelectedIndex = -1;
                    item.Selected = true;
                }
            }
        }
        /// <summary>
        /// Used to find controls on page
        /// </summary>
        /// <param name="CurrentCtrl"></param>
        /// <param name="ControlToFind"></param>
        /// <returns>Control search for or null</returns>
        public virtual Control FindControls(Control CurrentCtrl, string ControlToFind)
        {
            Control ctrl = null;

            try
            {
                if (CurrentCtrl.NamingContainer != null)
                    ctrl = CurrentCtrl.NamingContainer.FindControl(ControlToFind);

                if (ctrl != null)
                    return ctrl;

                foreach (Control c in CurrentCtrl.Controls)
                {
                    if (ctrl == null)
                        ctrl = c.FindControl(ControlToFind);

                    if (ctrl != null)
                        break;
                    else
                        ctrl = FindControls(c, ControlToFind);
                }
            }
            catch
            {
            }
            return ctrl;
        }
        public virtual T FindControlOfType<T>(Control CurrentCtrl) where T : class
        {
            T ctrl = default(T);

            try
            {
                if (ctrl != null)
                    return ctrl;

                foreach (Control c in CurrentCtrl.Controls)
                {
                    if (c is T)
                        ctrl = c as T;

                    if (ctrl != null)
                        break;
                    else
                        FindControlOfType<T>(c);
                }
            }
            catch { }

            return ctrl;
        }
        public virtual List<T> FindAllControlOfType<T>(List<T> ctrlList, Control CurrentCtrl) where T : class
        {
            try
            {
                foreach (Control c in CurrentCtrl.Controls)
                {
                    if (c is T)
                        ctrlList.Add(c as T);

                    FindAllControlOfType<T>(ctrlList, c);
                }
            }
            catch { }

            return ctrlList;
        }
        public virtual Control FindControlsUp(Control CurrentCtrl, string ControlToFind)
        {
            try
            {
                Control ctrl = CurrentCtrl.FindControl(ControlToFind);

                if (ctrl != null)
                    return ctrl;

                if (CurrentCtrl.NamingContainer != null)
                {
                    FindControlsUp(CurrentCtrl.NamingContainer, ControlToFind);
                }
            }
            catch
            {

            }
            return null;
        }

        public virtual Image FindImage(Control currentControl)
        {
            Image currentImage = null;

            if (currentControl is Image)
            {
                currentImage = currentControl as Image;
            }
            else
            {
                foreach (Control c in currentControl.Controls)
                {
                    currentImage = FindImage(c);
                }
            }
            return currentImage;
        }

        /// <summary>
        /// Gets the container for the current control
        /// </summary>
        /// <param name="currentControl"></param>
        /// <returns></returns>
        public virtual DataContainer GetParentDataContainer(Control currentControl)
        {
            DataContainer dataContainer = null;
            if (currentControl != null)
            {
                while (currentControl.Parent != null && !(currentControl is Page))
                {
                    currentControl = currentControl.Parent;

                    dataContainer = DataContainer.GetDataContainer(currentControl);

                    if (dataContainer != null)
                        return dataContainer;
                }
            }
            return null;
        }
    }

    public class DataContainer
    {
        private Control _control;
        public Control Control
        {
            get { return _control; }
        }

        private DataContainer(Control control)
        {
            _control = control;
        }

        public T GetObject<T>() where T : class
        {
            if (_control is IDataItemContainer)
            {
                IDataItemContainer c = (IDataItemContainer)_control;
                if (c.DataItem is T)
                    return (T)c.DataItem;
            }
            return null;
        }

        public static DataContainer GetDataContainer(Control control)
        {
            if (control is IDataItemContainer)
                return new DataContainer(control);
            else
                return null;
        }
    }
}